
#include "stdrope.h"
#include "util.h"

#include "hallib.h"
#include "sallib.h"

#include "ostime.h"
#include "log.h"
#include "uart.h"
#include "gpio.h"
#include "can.h"
#include "cli.h"

static void TEST_Gpio(char *pArg);
static void TEST_Uart(char *pArg);
static void TEST_Can(char *pArg);

static hd_t s_hUartHandle = NULL;
static hd_t s_hCanHandle = NULL;

int main(int argc, char *argv[]) 
{
    UART_INIT_CB_S stUartOpt =
    {
        .uiBaudrate = 115200,
        .ucDataBits = 8,
        .ucStopBits = 1,
        .ucParity = PARITY_NONE,
    };
    CLI_INFO_S astCliInfo[] = 
    {
        {"gpio", "gpio test cmd", TEST_Gpio},
        {"uart", "uart test cmd", TEST_Uart},
        {"can",  "can test cmd", TEST_Can}, 
    };
    uint32_t auiCanFilterData[] =
    {
        0x11, 0x12, 0x13, 0x14, 0x15,// 0x708,
    };
    VAR_ARRAY_S stCanFilter;

    SAL_PreInstall();
    HAL_Install();
    SAL_MainInstall();
    
    CLI_Register(astCliInfo, _ARRAY_SIZE(astCliInfo));    
    
    s_hUartHandle = HAL_Open(HW_UART, HAL_UART2);
    if (0 > HAL_Ctrl(s_hUartHandle, CTRL_UART_INIT, &stUartOpt))
    {
        LOG_ERR("MAIN", "uart init fail.\n");
    }

    s_hCanHandle = HAL_Open(HW_CAN, HAL_CAN0);
    stCanFilter.uiLength = _ARRAY_SIZE(auiCanFilterData);
    stCanFilter.ptr = auiCanFilterData;
    if (0 > HAL_Ctrl(s_hCanHandle, CTRL_CAN_FILTER, &stCanFilter))
    {
        LOG_ERR("MAIN", "can set filter fail.\n");
    }

    while (1)
    {
        LOG_Flush(0);
	    osSleepus(1000);
    }
    return 0;
}

static void TEST_Gpio(char *pArg)
{
    char *pNextArg = NULL;
    char acKey[CLI_CMD_NAME_MAX_LEN];
    
    pNextArg = CLI_KeyNext(pArg, acKey);
    if (0 == strcmp(acKey, "set"))
    {
        uint32_t uiGpioIdx = 0;
        uint32_t uiValue = 0;

        pNextArg = CLI_KeyNext(pNextArg, acKey);
        uiGpioIdx = atoi(acKey);
        pNextArg = CLI_KeyNext(pNextArg, acKey);
        uiValue = atoi(acKey);
        if (0 > HAL_WriteOnce(HW_GPIO, uiGpioIdx, (uint8_t *)&uiValue, sizeof(uint32_t), 0))
        {
            CLI_Output("gpio:%d set:%d fail\n", uiGpioIdx, uiValue);
        }
        else
        {
            CLI_Output("gpio:%d set:%d succ\n", uiGpioIdx, uiValue);
        }
    }
    else if (0 == strcmp(acKey, "get"))
    {
        uint32_t uiGpioIdx = 0;
        uint32_t uiValue = 0;
        pNextArg = CLI_KeyNext(pNextArg, acKey);
        uiGpioIdx = atoi(acKey);
        if (0 > HAL_ReadOnce(HW_GPIO, uiGpioIdx, (uint8_t *)&uiValue, sizeof(uint32_t), 0))
        {
            CLI_Output("gpio:%d get fail\n", uiGpioIdx);
        }
        else
        {
            CLI_Output("gpio:%d status:%d\n", uiGpioIdx, uiValue);
        }
    }
    else
    {
        CLI_Output("ERR: INVALID CMD.\n");
    }
    CLI_Exit();
}

static void TEST_Uart(char *pArg)
{
    char acKey[CLI_CMD_NAME_MAX_LEN];
    char acBuffer[256] = {0};

    CLI_KeyNext(pArg, acKey);
    if (0 == strcmp(acKey, "recv"))
    {
        if (0 < HAL_Read(s_hUartHandle, (uint8_t *)acBuffer, 256, H_FLAG_BLOCK))
        {
            CLI_Output("uart recv: %s\n", acBuffer);
        }
        else
        {
            CLI_Output("ERR: uart recv fail.\n");
        }
    }
    else if (0 == strcmp(acKey, "send"))
    {
        char acData[3] = { 0x16, 0x54, 0x0D };
        if (0 < HAL_Write(s_hUartHandle, (uint8_t *)acData, sizeof(acData), 0))
        {
            CLI_Output("uart send ok.\n");
        }
        else
        {
            CLI_Output("ERR: uart send fail.\n");
        }
    }
    else
    {
        CLI_Output("ERR: INVALID CMD.\n");
    }
    CLI_Exit();
}

static void TEST_Can(char *pArg)
{
    char acKey[CLI_CMD_NAME_MAX_LEN];
    CAN_MSG_S stCanMsg;

    CLI_KeyNext(pArg, acKey);
    if (0 == strcmp(acKey, "recv"))
    {
        if (0 < HAL_Read(s_hCanHandle, (uint8_t *)&stCanMsg, sizeof(CAN_MSG_S), H_FLAG_BLOCK))
        {
            CLI_Output("can recv, id:0x%x, len:%d data:0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
                    stCanMsg.uiCanId, stCanMsg.uiLen, stCanMsg.aucData[0], stCanMsg.aucData[1], stCanMsg.aucData[2], stCanMsg.aucData[3], stCanMsg.aucData[4], stCanMsg.aucData[5], stCanMsg.aucData[6], stCanMsg.aucData[7]);
        }
        else
        {
            CLI_Output("ERR: can recv fail.\n");
        }
    }
    else if (0 == strcmp(acKey, "send"))
    {
        stCanMsg.uiCanId = 0x16;
        stCanMsg.uiLen = 8;
        stCanMsg.aucData[0] = 0x16;
        stCanMsg.aucData[1] = 0xBB;
        stCanMsg.aucData[2] = 0x00;
        stCanMsg.aucData[3] = 0x00;
        stCanMsg.aucData[4] = 0x00;
        stCanMsg.aucData[5] = 0x00;
        stCanMsg.aucData[6] = 0x00;
        stCanMsg.aucData[7] = 0x7E;

        if (0 < HAL_Write(s_hCanHandle, (uint8_t *)&stCanMsg, sizeof(CAN_MSG_S), 0))
        {
            CLI_Output("can send ok.\n");
        }
        else
        {
            CLI_Output("can send fail.\n");
        }
    }
    else
    {
        CLI_Output("ERR: INVALID CMD.\n");
    }
    CLI_Exit();
}

